package ewa

import (
  	 "fmt"
     "net/http"
  	"encoding/json"
    "github.com/rs/xid"
	"github.com/labstack/echo"
  "strings"
)

const (
  AsyncFlag = 1
  SyncFlag = 2
)

type ACK struct {
  Reply     []string  `json:"Reply"`
}


func PostFormParamsJson(c echo.Context) string {
  var obj map[string]interface{}
  form,_ := c.FormParams()
  //mjson,_ :=json.Marshal(form)
  //jForm :=string(mjson); fmt.Printf("print jForm:%s\n",jForm)
  ClientIP := `{"ClientIP": "`+c.RealIP()+`"}`
  //fmt.Printf("ClientIP: %s\n", ClientIP)
  	json.Unmarshal([]byte(ClientIP), &obj)
	obj["Scheme"] = c.Scheme()
  	obj["Form"] = form
    obj["ApiPath"] = c.Path()

  jData,_ := json.Marshal(obj)
  //fmt.Println(string(jData))
  
  return string(jData)
}

func AckFormJson(reply string) string {
  //fmt.Printf("%s\n", reply)
  var obj map[string]interface{}
  ClientIP := `{"ClientIP": "`+""+`"}`
  json.Unmarshal([]byte(ClientIP), &obj)

  //必须使用json数组格式
  //    {"Key": ["String Value"]}
  Form := `{"Reply": ["`+reply+`"]}`
  obj["Form"] = Form

  obj["Scheme"] = ""
  obj["ApiPath"] = ""
  obj["XID"]  = ""
  
  jData,_ := json.Marshal(obj)
  s:=string(jData)
  // 去掉字符串中的转义符号\
  s=strings.Replace(s, `\"`, `"`, -1)
  s=strings.Replace(s, `"{`, `{`, -1)
  s=strings.Replace(s, `}"`, `}`, -1)
  return s
}

func PostFormParamsJsonV2(c echo.Context, flag int) (string, string) {
  var obj map[string]interface{}
  form,_ := c.FormParams()
  //mjson,_ :=json.Marshal(form)
  //jForm :=string(mjson); fmt.Printf("print jForm:%s\n",jForm)
  ClientIP := `{"ClientIP": "`+c.RealIP()+`"}`
  //fmt.Printf("ClientIP: %s\n", ClientIP)
    json.Unmarshal([]byte(ClientIP), &obj)
  obj["Scheme"] = c.Scheme()
    obj["Form"] = form
    obj["ApiPath"] = c.Path()

  var XID string = ""
  if flag == SyncFlag {
    XID = xid.New().String()
    obj["XID"] = XID
  }
  jData,_ := json.Marshal(obj)
  //fmt.Println(string(jData))
  
  return string(jData), XID
}

func AsyncApiResponse(uri string, c echo.Context) error{
    // redis lpush
    var l string
    r:=CreateRedisConn(RedisConnArgs_)
    jData, _ := PostFormParamsJsonV2(c, AsyncFlag)  // 异步消息标志
    l=fmt.Sprintf("Asyncmes/> %s", jData); Log(l)
    RedisQlPush(r, CfgRoute.MApiAttr[uri].Queue, jData)
    RemoveRedisConn(r)
    l=fmt.Sprintf("---Redis/> Asynchronous API '%s' lpush message to redis queue '%s': OK", uri, CfgRoute.MApiAttr[uri].Queue);Log(l)
    return c.String(http.StatusOK, l)
}

func SyncApiResponse(uri string, c echo.Context) error{
    // redis lpush
    var l string
    r:=CreateRedisConn(RedisConnArgs_)
    jData,XID := PostFormParamsJsonV2(c, SyncFlag)  // 同步消息标志
    l=fmt.Sprintf("Syncmess/> %s", jData); Log(l)
    RedisQlPush(r, CfgRoute.MApiAttr[uri].Queue, jData)
    // redis queue rpop string
    l=fmt.Sprintf("---Redis/> Synchronous API '%s' lpush message to redis queue '%s': OK, Waitting ACK ...", uri, CfgRoute.MApiAttr[uri].Queue);Log(l)
   
    var f ACK
    var queue string = XID
    m:=MessageBRPOP(RedisConnArgs_, queue, &f, 0); m=m

    //fmt.Println(m)
    R:=fmt.Sprintf("%s", f.Reply[0]); Log(R)
    RemoveRedisConn(r)
    return c.String(http.StatusOK, R)
}


func InnerCfgRouteInit(e *echo.Echo) {
  for i:=0; i<len(CfgRoute.L_NRPage); i++ {
     RouteRegistry_NonCookieTokenGet(CfgRoute.L_NRPage[i], e, CbNonCookieTokenGet)
  }
  /*
  for i:=0; i<len(CfgRoute.L_NRApi); i++ {
     RouteRegistry_NonCookieTokenPost( CfgRoute.L_NRApi[i], e, CbNonCookieTokenPost)
  }
  */
  for i:=0; i<len(CfgRoute.L_RPage); i++ {
     RouteRegistry_CookieTokenGet( CfgRoute.L_RPage[i], e, CbCookieTokenGet)
  }
  /*
  for i:=0; i<len(CfgRoute.L_RApi); i++ {
     RouteRegistry_CookieTokenPost( CfgRoute.L_RApi[i], e, CbCookieTokenPost)
  }
  */
  var apis []string = MapAttrKeys(CfgRoute.MApiAttr)

  for i:=0; i < len(apis); i++ {
    if CfgRoute.MApiAttr[apis[i]].Restrict == false {
        RouteRegistry_NonCookieTokenPost( apis[i], e, CbNonCookieTokenPost)
    }else if CfgRoute.MApiAttr[apis[i]].Restrict == true {
         RouteRegistry_CookieTokenPost( apis[i], e, CbCookieTokenPost) 
    }

  }
}
